《C++面向对象软件设计及构建》文章翻译:2.5默认参数,2.5 Default Arguments
默认参数,本身是正式参数,当调用者未提供实际的参数值的时候,会被自动赋予一个值(即为默认值)。当然,实际提供的参数值,如果存在的话,就会覆盖掉默认值。
以下这个基于Frame 类的示例,展示了默认参数的语法和用法。
class Frame {
private:
...
public:
...
void Resize (int width = 100, int height = 150);
...
};
在这个示例中,width 和height 参数都带有默认值。要体验默认值的效果的话,则观摩以下示例中对于Resize 方法的调用:
Frame window (100, 100, 300, 400);
...
window.Resize(200, 250); // 情景1
window.Resize(200); // 情景2
window.Resize(); // 情景3
在第一种情景中,窗口的大小被改变为200 x 250:由于两个参数都正常提供了,所以默认值被忽略。在第二种情景中,Frame 对象的大小被改变为200 x 150:对于缺失的第二个(height)参数,使用了默认值150,而对于第一个(width)参数,则使用此处所提供的200 作为其值。第三种情景中,窗口的大小被改变为100 x 150,因为两个参数都是使用的默认值。
在构造函数中也可以使用默认参数值。例如,Frame 类,可重新定义如下:
class Frame {
private:
...
public:
Frame( char *name, int initXcoord = 50, int initYcoord = 50,
int initWidth = 100, int initHeight = 100 );
...
};
这个唯一的构造函数,可按照以下不同方式使用:
Frame display1("Fully Specified", 200, 200, 300, 350);
Frame display2("No Height", 200, 200, 300);
Frame display3("Position Only", 200, 200);
Frame display4("No YCoordinate", 200)
Frame display5("Name Only");
Frame对象display1,被赋予了一个名字,会处于位置(200,200),其形状会是300 x 350。Frame对象display2,与display1 类似,区别就在于,它的高度是默认高度100,其值由initHeight 的默认值所指定。Frame对象display3,被赋予了一个名字,会处于位置(200,200),其形状会是100 x 100,形状由initWidth 和initHeight 的默认值确定。Frame对象display4,与display3 类似,区别只在于,它的名字不同,并且其位置是(200,50),此处的y坐标为50,是由参数initYcoord 的默认值决定的。最后,是display5,它会有一个明确赋予的名字,而它的位置((50,50))和形状(100 x 100)则是由默认值决定。
注意,配合重载方法的使用,再加上默认参数的使用,就给予了方法的调用者以更多的灵活性,可以按照自己需要的方式来调用该方法。调用者只需要指定那些必要的参数,而让其它参数直接使用默认值。如果调用者需要更准确地控制方法中的参数的话,那么,也可以使用自己提供的值来覆盖掉默认值。
以下情况下可以使用默认值:
•.默认值可用来代替某个常见的值
•.作为一个“安全”值来使用,以确保做出有意义的计算
•.作为一个“无意义”(例如,超出范围)值来使用,使得被调用的方法使用某种算法来对此处缺失的参数值做出补偿
常见或安全默认值的例子包括:某个整数“计数器”,它的默认初始值是0;或者,某个字符串值,它的初始值是空白或是无效。设想Frame 类的某个变种,其中,x 坐标、y 坐标、高度和宽度的默认值都是-1,显然这些默认值是无意义的。Frame的构造函数,在遇到(部分的)这样的默认值的时候,就会使用某个内部算法,以确定,对于这些默认值,该使用一个什么样的合理的值。举个例子,在这种算法中,可能会尽量做到让本窗口与屏幕上其它窗口的重叠区域最小。
对于默认值的使用规则是:不带默认值的参数,不允许出现在带有默认值的参数之后(右边)。以下示例,展示了这条规则的必要性:
class Cube {
public:
...
Resize( int height = 10, int width = 20, int depth);
...
};
注意,这个示例,违反了前面所说的默认参数规则。因为,depth 参数没有默认值,而它却出现在拥有默认值的width 之后。再结合以下使用 Resize 方法的代码来看:
Cube cube;
...
cube.Resize(30, 50);
此处,对于Resize 的调用,可能会表示三种不同的意义:
cube.Resize(10, 30, 50); // 使用height 的默认值
cube.Resize(30, 20, 50); // 使用width 的默认值
cube.Resize(30, 50); // 错误 - 不提供 depth参数
通过上面说的那条规则,就可以避免产生这种歧义,这对于编译器和程序猿来说都是好事。
任务
Your opinionsHxLauncher: Launch Android applications by voice commands